package com.zhou.common.quartz.test.task;


import lombok.RequiredArgsConstructor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;

/**
 * @author xianfeng
 * @date 2023/12/20 14:52
 * @description:
 */
@RequiredArgsConstructor
@Component
public class ScheduledTasks {

    private static final Logger log = LoggerFactory.getLogger(ScheduledTasks.class);
    private static final SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");
    private final TestAsyncService testAsyncService;

    /**
     * corn 表达式
     * fixedDelay 在上一次调用结束和下一次调用开始之间的固定时间内执行(它指定从任务完成开始测量的调用之间的时间间隔)
     * fixedRate 以固定的时间间隔执行带注释的方法(从每次调用的开始时间开始测量)
     * initialDelay 在第一次执行{fixedRate}或{fixedDelay}任务之前延迟的时间单位数
     */
    @Scheduled(fixedRate = 50000)
    public void reportCurrentTime() throws ExecutionException, InterruptedException {
        log.info("The time is now {}", dateFormat.format(new Date()));
        Future<String> stringFuture = testAsyncService.testAsync1();
        log.info("future获取的结果={}", stringFuture.get());
        CompletableFuture<String> stringCompletableFuture = testAsyncService.testAsync2();
        stringCompletableFuture.whenComplete((res, throwable) -> {
            log.info("completable future获取的结果={}", res);
            log.info("completable future throwable={}", throwable);
        });
        CompletableFuture<String> asyncException = testAsyncService.testAsyncException();
        CompletableFuture<String> asyncWithPkgException = asyncException.whenComplete((res, throwable) -> {
            log.info("completable future error 获取的结果={}", res);
            log.info("completable future error throwable={}", throwable);
        }).exceptionally(throwable -> {
            log.info("completable future error 捕获到异常");
            return "异常时返回的结果";
        });
        //asyncException.get()抛出的异常，无法打印traceId
//        log.info("completable future 最终的结果 {}", asyncException.get());
        //注意asyncException.get()和asyncWithPkgException.get()的区别
        log.info("completable future 最终的结果 {}", asyncWithPkgException.get());
    }

    /**
     * 错误的获取异步返回结果时，异常是否打印
     * 错误的类型或void 则会打印出异常结果
     */
    @Scheduled(fixedRate = 50000)
    public void reportWithAsyncError() {
        log.info("The time is now {}", dateFormat.format(new Date()));
        testAsyncService.testAsyncException1();
        log.info("执行不需要返回值的错误情况");
    }

    /**
     * 获取了结果，又不调用get方法，异常会被吞掉的
     *
     * @throws ExecutionException
     * @throws InterruptedException
     */
    @Scheduled(fixedRate = 50000)
    public void reportWithAsyncError1() throws ExecutionException, InterruptedException {
        log.info("------开始执行定时任务，测试定时任务抛出异常");
        Future<String> stringFuture = testAsyncService.testAsyncException2();
    }

    /**
     * 获取了结果，调用get方法，异常会被打印出来的
     *
     * @throws ExecutionException
     * @throws InterruptedException
     */
    @Scheduled(fixedRate = 50000)
    public void reportWithAsyncError2() throws ExecutionException, InterruptedException {
        log.info("------开始执行定时任务，测试定时任务抛出异常");
        Future<String> stringFuture = testAsyncService.testAsyncException2();
        log.info("执行不需要返回值的错误情况{}", stringFuture.get());
    }

}
